<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>贪吃蛇绘制</title>
    <!-- 设置一个背景色、 -->
    <style>
        canvas {
            /* 在这里要居中的时候，要先转成块级元素 */
            display: block;
            margin: 0 auto;
            background-color: #33cc99;
        }
    </style>
</head>

<body>
    <!-- 准备画布 -->
    <canvas width="500" height="500" id="huabu">
    
</canvas>
</body>

<script>
    // 通过 js 代码来绘制网格
    // 获取画布对象
    let huabu = document.getElementById('huabu');
    // 获取绘制工具箱
    let tools = huabu.getContext('2d');
    // 从画图工具箱取出要使用的工具;
    // 随机生成x 和 y轴的坐标
    let x = Math.floor(Math.random() * 20) * 25;
    let y = Math.floor(Math.random() * 20) * 25;
    let isEated = false;

    // 每次移动的距离为一格(默认就是在这个位置出发)
    let snake = [{
        x: 3,
        y: 0
    }, {
        x: 2,
        y: 0
    }, {
        x: 1,
        y: 0
    }]

    let directionX = 1;
    let directionY = 0;

    // 判断游戏是否结束
    let isGameOver = false;

    document.addEventListener('keydown', (e) => {
        let k = e.keyCode;
        // 上： 38 下： 40 左：37 右：39
        if (k === 38) {
            directionX = 0
            directionY = -1
        } else if (k === 40) {
            directionX = 0
            directionY = 1
        } else if (k === 37) {
            directionX = -1
            directionY = 0
        } else if (k === 39) {
            directionX = 1
            directionY = 0
        }
    })

    // 利用定时器，让贪吃蛇动起来
    setInterval(() => {
        if (isGameOver) {
            return
        }
        // 只需要将擦除 -> 重绘 的代码放里面即可(记得每次都先擦除画布再重绘一次)
        tools.clearRect(0, 0, 500, 500);


        // 注意：食物有默认的行为，刚开始是不动 的，被蛇吃后才会动

        // -------------绘制食物开始------------
        // 这段代码的意思是: 只有食物被吃掉了,才会生成新的食物
        if (isEated) {
            // 在这里是对 x 和 y 进行重新赋值，不用加 var 声明
            x = Math.floor(Math.random() * 20) * 25;
            y = Math.floor(Math.random() * 20) * 25;
        }

        // 设置矩形的颜色
        tools.fillStyle = '#fff000';
        // 画一个矩形
        // fillRect(x,y,width,height)
        // 不能随机生成 x,y 
        // 随机生成一个位置 Math.random() 生成一个随机数 * 25就得到一个范围
        // 问题： 如果根据 Math.random() 得到一个 [0,19] 并且 0 和 19 都能取到的值？
        // 解决方案: Math.random() * 20 => [0,1) * 20 => [0,20)

        // Math.floor()  向下取整
        tools.fillRect(x, y, 25, 25);
        // -------------绘制食物结束------------

        // ----------绘制贪吃蛇开始---------
        // 说明: 贪吃蛇随着 擦除 重绘,会动起来

        // 蛇已经动起来，默认向右： x + 1,y 不变
        // 水平向左： x -1y 不变
        // 垂直向下：y +1 x 不变
        // 垂直向上: y -1  x 不变

        // 新添加的节，是上一次的蛇头位置再加1，就得到了
        let oldHead = snake[0];
        let newHead = {
            x: oldHead.x + directionX,
            y: oldHead.y + directionY
        }

        // 在这里做一个边界的判定
        console.log(newHead.x * 30); //蛇移动的距离

        // 1.如果蛇头的 y 坐标比0小，说明游戏结束
        if (newHead.y < 0 || newHead.x < 0 || newHead.x * 30 >= 600 || newHead.y * 30 >= 600) {
            // 游戏就结束了
            isGameOver = true;
            alert('Game over···请刷新页面重新游戏')
        } else {
            snake.unshift(newHead); //向数组的开头添加一个或多个元素，并返回新的长度
            // 蛇吃食物分析：
            // 当蛇头的坐标 和 食物的坐标重合的时候，就表示食物被吃掉了
            // 此时应该做两件事
            // 1. 让 isEated 变成 true，表示食物被吃掉
            // 2. 让 蛇 的身体增加一节
            if (snake[0].x * 25 === x && snake[0].y * 25 === y) {
                // 当蛇头的 x 和 Y 坐标都与 食物的 x和y坐标 重合，才证明食物被吃了
                isEated = true;
                // 如果蛇吃到了食物，就不执行 pop() 删除最后一节
            } else {
                // 在这里重新把 isEated 设置为 false
                isEated = false; // 重新设置食物没被吃掉
                // 表示蛇没吃到食物
                snake.pop(); //
            }
        }
        // ----------绘制贪吃蛇结束---------

        // 默认移动方向为水平向右
        // 绘制蛇头的颜色,每一届都是一个矩形
        for (var i = 0; i < snake.length; i++) {
            if (i === 0) {
                // 只有蛇头是紫色的，0 的时候
                tools.fillStyle = 'purple'
            } else {
                tools.fillStyle = 'blue'
            }
            tools.fillRect(snake[i].x * 25, snake[i].y * 25, 25, 25);
        }

        // -----------绘制网格开始----------
        // 找位置
        // 起点坐标
        // 规律： (0,25 * N + 0.5)(500, 25 * N + 0.5)

        for (let i = 1; i < 20; i++) {
            tools.moveTo(0, 25 * i + 0.5);
            // 终点坐标
            tools.lineTo(500, 25 * i + 0.5);

            tools.moveTo(25 * i + 0.5, 0);
            // 终点坐标
            tools.lineTo(25 * i + 0.5, 500);
        }

        // 设置绘制的画笔颜色
        tools.strokeStyle = 'white';
        // 绘制
        tools.stroke();
        // -----------绘制网格结束----------
    }, 1000 / 3); //1000/3 为 1秒执行 3 次操作
</script>

</html>